package com.jiang.demo.aspect;

import com.jiang.demo.common.MSGException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;

/**
 * ---------------------------------------------------------------------------------------------------------------
 * - 2024-06-01 15:24 - jiangshaoneng@163.com -
 * ---------------------------------------------------------------------------------------------------------------
 * -      ██╗██╗ █████╗ ███╗   ██╗ ██████╗ ███████╗██╗  ██╗ █████╗  ██████╗ ███╗   ██╗███████╗███╗   ██╗ ██████╗
 * -      ██║██║██╔══██╗████╗  ██║██╔════╝ ██╔════╝██║  ██║██╔══██╗██╔═══██╗████╗  ██║██╔════╝████╗  ██║██╔════╝
 * -      ██║██║███████║██╔██╗ ██║██║  ███╗███████╗███████║███████║██║   ██║██╔██╗ ██║█████╗  ██╔██╗ ██║██║  ███╗
 * - ██   ██║██║██╔══██║██║╚██╗██║██║   ██║╚════██║██╔══██║██╔══██║██║   ██║██║╚██╗██║██╔══╝  ██║╚██╗██║██║   ██║
 * - ╚█████╔╝██║██║  ██║██║ ╚████║╚██████╔╝███████║██║  ██║██║  ██║╚██████╔╝██║ ╚████║███████╗██║ ╚████║╚██████╔╝
 * -  ╚════╝ ╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝ ╚═════╝ ╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═══╝╚══════╝╚═╝  ╚═══╝ ╚═════╝
 * ---------------------------------------------------------------------------------------------------------------
 * 权限验证逻辑,配标识 @AuthResources的方法执行前需要走的验证逻辑
 * ---------------------------------------------------------------------------------------------------------------
 */
@Slf4j
@Component
@Aspect
@Order(2)
public class AuthResourcesAspect {

    @Pointcut("@annotation(com.jiang.demo.aspect.AuthResources)")
    public void logPointCut() {}

    @Around("logPointCut()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes)
                Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        String resource = request.getRequestURI();

        // 获取用户信息, 以及包含的资源
        String username = request.getHeader("Jiang-Client-Username");
        String token = request.getHeader("Jiang-Client-Token");
        String[] userResources = getResourcesByUser(username);

        // 管理员有全部的权限
        if(Arrays.asList(userResources).contains("admin")){
            return pjp.proceed();
        }

        // 获取本方法允许的资源
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        AuthResources authResources = method.getAnnotation(AuthResources.class);
        String[] resources = authResources.value();

        boolean pass = Arrays.stream(userResources).anyMatch(Arrays.asList(resources)::contains);
        if (!pass) {
            log.error("[auth_fail] user:{} fail to get resource:{}", username, resource);
            return MSGException.AUTH_ERROR;
        }
        // 执行目标方法
        return pjp.proceed();
    }

    // TODO 查询用户包含的权限
    public String[] getResourcesByUser(String username){
        return new String[]{};
    }
}
